package com.dolawing.phonecallapp.listenphonecall;


import android.Manifest;
import android.annotation.SuppressLint;
import android.app.KeyguardManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.PowerManager;
import android.os.RemoteException;
import android.telecom.TelecomManager;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.RemoteViews;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationCompat;

import com.android.internal.telephony.ITelephony;
import com.dolawing.phonecallapp.App;
import com.dolawing.phonecallapp.MainActivity;
import com.dolawing.phonecallapp.R;
import com.dolawing.phonecallapp.blacknumber.db.BlackNumberDao;
import com.dolawing.phonecallapp.keepAliveUi.KeepManager;
import com.dolawing.phonecallapp.phoneLog.CallDetails;
import com.dolawing.phonecallapp.phoneLog.PhoneCallUtils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 电话监听的封装版
 */
public class CallListenerService2 extends Service {
    private int notifyId = 1;
    private String CHANNEL_ID = "com.dolawing.phonecall.alarm.AppService";
    private String CHANNEL_NAME = "dolawing";
    private NotificationManager notificationManager;
    private NotificationCompat.Builder builder;
    //******************电话参数**********************
    private Context mContext;
    private Handler mHandler= null;


    //************************************************
    private View phoneCallView;
    private TextView tvCallNumber;
    private Button btnOpenApp;

    private WindowManager windowManager;
    private WindowManager.LayoutParams params;

    private PhoneStateListener phoneStateListener;
    private TelephonyManager telephonyManager;

    private String callNumber;
    private boolean hasShown;
    private boolean isCallingIn;

    private BlackNumberDao blackNumberDao;

    @Override
    public void onCreate() {
        super.onCreate();
        mContext = this;
        blackNumberDao = new BlackNumberDao(mContext);
        mHandler = new Handler(Looper.getMainLooper());
        //获取锁
        acquireWakeLock();
        initPhoneStateListener();
        initPhoneCallView();
        //初始化 通知，Android O （8.0）以上版本需要渠道 ,创建NotificationManager对通知进行管理
        initNotification();
        Log.i("Info",CallListenerService2.class.getSimpleName());
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        /**
         * 显示当前任务和执行时间
         */
        new Thread(new Runnable(){
            @Override
            public void run() {
                RemoteViews mRemoteViews = new RemoteViews(getPackageName(),R.layout.view_notification);
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String nowTimes = sdf.format(new Date());
                Log.i("执行onStartCommand执行时间",nowTimes);
                // 封装自定义的布局
                mRemoteViews.setTextViewText(R.id.appCreateTimeView,nowTimes);
                mRemoteViews.setTextViewText(R.id.serviceInfo1View,App.getAlarmInstance().getCreateRunningInfo());
                mRemoteViews.setTextViewText(R.id.serviceInfo2View,App.getAlarmInstance().getOnStartRunningInfo());
                while(true){
                    Calendar calendar = Calendar.getInstance();
                    int hour = calendar.get(Calendar.HOUR_OF_DAY);
                    int min = calendar.get(Calendar.MINUTE);
                    int sec = calendar.get(Calendar.SECOND);
                    String timestamps = ""+hour + "时" + min+"分" + sec +"秒";//记录时间
                    mRemoteViews.setTextViewText(R.id.currentTimesView,timestamps);
                    builder.setContent(mRemoteViews);
                    startForeground(notifyId, builder.build());
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();

        return Service.START_NOT_STICKY;
    }

    /**
     * 初始化来电状态监听器
     */
    private void initPhoneStateListener() {
        phoneStateListener = new PhoneStateListener() {
            @Override
            public void onCallStateChanged(int state, String incomingNumber) {
                super.onCallStateChanged(state, incomingNumber);
                Log.i("Info","初始化监听StateListener状态发生变化");
                //电话号码
                callNumber = incomingNumber;

                //获取手机当前、上一次通话状态值
                int currentState = PhoneCallSettings.currentState;
                int oldState =  PhoneCallSettings.getInstance(mContext).getOldState();
                switch( state ){
                    case TelephonyManager.CALL_STATE_IDLE : // 电话挂断
                        currentState = PhoneCallSettings.CALL_TYPE_IDEL;
                        dismiss();
                        break;
                    case TelephonyManager.CALL_STATE_OFFHOOK :  // 来电接通 或者 去电
                        currentState = PhoneCallSettings.CALL_TYPE_CALLING;
                        updateUI();
                        show();
                        break;
                    case TelephonyManager.CALL_STATE_RINGING : // 电话响铃
                        currentState = PhoneCallSettings.CALL_TYPE_RING;
                        isCallingIn = true;
                        updateUI();
                        show();
                        break;
                }
                Log.i("oldState------>", oldState+"");
                Log.i("currentState------>", currentState+"");

                //保存当前通话状态值
                PhoneCallSettings.getInstance(mContext).setOldState(currentState);
                //去电：
                if(oldState == PhoneCallSettings.CALL_TYPE_IDEL && currentState == PhoneCallSettings.CALL_TYPE_CALLING ){
                    Log.i("------>", "去电拨号"); // 初步状态:空闲 + 当前状态:通话中
                    PhoneCallSettings.getInstance(mContext).setHasOffHook(false);
                    //业务： 拨打电话，响铃计时 开始时间
                    PhoneCallSettings.getInstance(mContext).setOutComingRingStartTimestamp(System.currentTimeMillis());


                }
                //来电
                if (oldState == PhoneCallSettings.CALL_TYPE_IDEL && currentState == PhoneCallSettings.CALL_TYPE_RING){
                    Log.i("CALL_STATE_IDLE--->","来电响铃"); // 初步状态:空闲 + 当前状态:来电响铃
                    PhoneCallSettings.getInstance(mContext).setHasOffHook(false);
                    //业务： 来电，响铃计时 开始时间
                    PhoneCallSettings.getInstance(mContext).setInComingRingStartTimestamp(System.currentTimeMillis());
                }

                if(oldState == PhoneCallSettings.CALL_TYPE_RING && currentState == PhoneCallSettings.CALL_TYPE_CALLING ){
                    Log.i("------>","接听，开始通话。。。");  //初步状态:来电响铃 + 当前状态:通话中
                    //接听分类：1、接听方接听，2、拨打方接听
                    PhoneCallSettings.getInstance(mContext).setHasOffHook(true);  //true表示通话中
                    //业务： 响铃计时 结束时间；接听计时，开始时间
                    PhoneCallSettings.getInstance(mContext).setInoutComingRingStopTimestamp(System.currentTimeMillis());
                    PhoneCallSettings.getInstance(mContext).setHoldOnStartTimestamp(System.currentTimeMillis());
                    //来电接听
                    if (PhoneCallSettings.getInstance(mContext).getInComingRingStartTimestamp() > 0){
                        Long ringTimes = PhoneCallSettings.getInstance(mContext).getInoutComingRingStopTimestamp() - PhoneCallSettings.getInstance(mContext).getInComingRingStartTimestamp();
                        Log.i("接通前，来电-电话响铃时长--->",ringTimes+"");
                        Toast.makeText(mContext,"接通前，来电-电话响铃时长--->"+ringTimes,Toast.LENGTH_LONG).show();
                    }else { //去电接听
                        Long ringTimes = PhoneCallSettings.getInstance(mContext).getInoutComingRingStopTimestamp() - PhoneCallSettings.getInstance(mContext).getOutComingRingStartTimestamp();
                        Log.i("接通前，去电-电话响铃时长--->",ringTimes+"");
                        Toast.makeText(mContext,"接通前，去电-电话响铃时长--->"+ringTimes,Toast.LENGTH_LONG).show();
                    }

                }else if(oldState == PhoneCallSettings.CALL_TYPE_CALLING && currentState == PhoneCallSettings.CALL_TYPE_IDEL
                        && PhoneCallSettings.getInstance(mContext).isHasOffHook()==true){
                    Log.i("------>", "挂断");   // 初步状态:通话中 + 当前状态:空闲 = 挂断
                    //挂断分类：1、接听方挂断，2、拨打方挂断
                    PhoneCallSettings.getInstance(mContext).setHasOffHook(false);
                    //业务1： 接听计时，结束时间
                    PhoneCallSettings.getInstance(mContext).setHoldOffStopTimestamp(System.currentTimeMillis());
                    Long talkingTimes =  PhoneCallSettings.getInstance(mContext).getHoldOffStopTimestamp() -  PhoneCallSettings.getInstance(mContext).getHoldOnStartTimestamp();
                    Log.i("电话接通时长--->",talkingTimes+"");
                    //业务2：上传通话记录 + 录音（已接通）
                   // printLastCallLog();
                    Toast.makeText(mContext,"电话接通时长--->"+talkingTimes,Toast.LENGTH_LONG).show();

                }else if(oldState == PhoneCallSettings.CALL_TYPE_CALLING && currentState == PhoneCallSettings.CALL_TYPE_IDEL
                        && PhoneCallSettings.getInstance(mContext).isHasOffHook()==false){
                    Log.i("------>", "去电取消");  //初步状态:通话中 + 当前状态:空闲 = 去电取消
                    //挂断分类：1、接听方挂断，2、拨打方挂断
                    PhoneCallSettings.getInstance(mContext).setHasOffHook(true);
                    //业务1： 响铃计时 结束时间
                    PhoneCallSettings.getInstance(mContext).setInoutComingRingStopTimestamp(System.currentTimeMillis());
                    //业务2：上传通话记录（未接通）
                    Long ringTimes = PhoneCallSettings.getInstance(mContext).getInoutComingRingStopTimestamp() - PhoneCallSettings.getInstance(mContext).getOutComingRingStartTimestamp();
                    Log.i("未接通，去电-电话响铃时长--->",ringTimes+"");

                    //业务2：上传通话记录 + 录音（已接通）
                    //printLastCallLog();
                    Toast.makeText(mContext,"未接通，去电-电话响铃时长--->"+ringTimes,Toast.LENGTH_LONG).show();

                }else if (oldState == PhoneCallSettings.CALL_TYPE_RING && currentState == PhoneCallSettings.CALL_TYPE_IDEL){
                    Log.i("CALL_STATE_IDLE--->","来电取消");  //初步状态:来电响铃 + 当前状态:空闲 = 来电取消
                    //取消分类：1、接听方取消，2、拨打方取消
                    PhoneCallSettings.getInstance(mContext).setHasOffHook(true);
                    //业务1： 响铃计时 结束时间
                    PhoneCallSettings.getInstance(mContext).setInoutComingRingStopTimestamp(System.currentTimeMillis());
                    Long ringTimes = PhoneCallSettings.getInstance(mContext).getInoutComingRingStopTimestamp() - PhoneCallSettings.getInstance(mContext).getInComingRingStartTimestamp();
                    Log.i("未接通，来电-电话响铃时长--->",ringTimes+"");
                    //业务2：上传通话记录（未接通）
                    //printLastCallLog();
                    Toast.makeText(mContext,"未接通，来电-电话响铃时长--->"+ringTimes,Toast.LENGTH_LONG).show();

                }


            }
        };

        // 设置来电监听器
        telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
        if (telephonyManager != null) {
            telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
        }

    }

    private void printLastCallLog(){
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                CallDetails callDetail = PhoneCallUtils.getLastOneCallDetails(mContext);
                Log.i("最后一通电话",callDetail.toString());
                Toast.makeText(mContext,callDetail.toString(),Toast.LENGTH_LONG).show();

            }
        },1000);
    }


    private void initPhoneCallView() {
        windowManager = (WindowManager) getApplicationContext()
                .getSystemService(Context.WINDOW_SERVICE);
        int width = windowManager.getDefaultDisplay().getWidth();
        int height = windowManager.getDefaultDisplay().getHeight();

        params = new WindowManager.LayoutParams();
        params.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
        params.width = width;
        params.height = WindowManager.LayoutParams.WRAP_CONTENT;
        params.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;

        // 设置图片格式，效果为背景透明
        params.format = PixelFormat.TRANSLUCENT;
        // 设置 Window flag 为系统级弹框 | 覆盖表层
        params.type = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ?
                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY :
                WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
//        params.type = WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;
        // 不可聚集（不响应返回键）| 全屏
        params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_FULLSCREEN
                | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
        // API 19 以上则还可以开启透明状态栏与导航栏
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            params.flags = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
                    | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION
                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    | WindowManager.LayoutParams.FLAG_FULLSCREEN
                    | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
        }

        FrameLayout interceptorLayout = new FrameLayout(this) {

            @Override
            public boolean dispatchKeyEvent(KeyEvent event) {

                if (event.getAction() == KeyEvent.ACTION_DOWN) {
                    if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {

                        return true;
                    }
                }

                return super.dispatchKeyEvent(event);
            }
        };

        phoneCallView = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE))
                .inflate(R.layout.view_phone_call, interceptorLayout);
        tvCallNumber = phoneCallView.findViewById(R.id.tv_call_number);
        btnOpenApp = phoneCallView.findViewById(R.id.btn_open_app);
        btnOpenApp.setOnClickListener(v -> {
            Intent intent = new Intent(getApplicationContext(), MainActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            CallListenerService2.this.startActivity(intent);
        });
    }

    /**
     * 显示顶级弹框展示通话信息
     */
    private void show() {
        KeyguardManager mKeyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
        boolean flag = mKeyguardManager.inKeyguardRestrictedInputMode();
        if (flag) {
            Log.i("手机状态","锁屏中。。。。。");
            Toast.makeText(this,"锁屏中。。。。。",Toast.LENGTH_LONG).show();
            PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
            @SuppressLint("InvalidWakeLockTag")
            PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP |
                    PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "bright");
            wl.acquire();
            wl.release();
            //启动 弹窗 Activity
            Handler mHandler = new Handler(getMainLooper());
            MyRunnable runnable = new MyRunnable(this);
            mHandler.postDelayed(runnable,3000);
        }else{
            if (!hasShown) {
                windowManager.addView(phoneCallView, params);
                hasShown = true;
            }
        }
    }
    class MyRunnable implements Runnable{
        private Context mCx;
        public MyRunnable(Context context){
            mCx = context;
        }
        @Override
        public void run() {
            Log.i("Thread","2秒执行结束...");
            KeepManager.getInstance().startKeep(mCx);
        }
    }
    /**
     * 取消显示
     */
    private void dismiss() {
        //关闭 弹窗 Activity
        KeepManager.getInstance().finishKeep();
        if (hasShown) {
            windowManager.removeView(phoneCallView);
            isCallingIn = false;
            hasShown = false;
        }
    }

    private void updateUI() {
        tvCallNumber.setText(formatPhoneNumber(callNumber));

        int callTypeDrawable = isCallingIn ? R.drawable.ic_phone_call_in : R.drawable.ic_phone_call_out;
        tvCallNumber.setCompoundDrawablesWithIntrinsicBounds(null, null,
                getResources().getDrawable(callTypeDrawable), null);
    }

    public static String formatPhoneNumber(String phoneNum) {
        if (!TextUtils.isEmpty(phoneNum) && phoneNum.length() == 11) {
            return phoneNum.substring(0, 3) + "-"
                    + phoneNum.substring(3, 7) + "-"
                    + phoneNum.substring(7);
        }
        return phoneNum;
    }

    //挂断电话 2
    private void endCall2(String phone) {
        boolean flag = false;//判断是否拦截成功
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            TelecomManager manager = (TelecomManager) getSystemService(Context.TELECOM_SERVICE);
            if (manager != null) {
                if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ANSWER_PHONE_CALLS) != PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(getApplicationContext(),"没有权限，拦截失败！",Toast.LENGTH_SHORT).show();
                }
                flag = manager.endCall();
            }
        }else {
            //ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE));
            try {
                //获取类
                @SuppressLint("PrivateApi")
                Class<?> serviceManager = Class.forName("android.os.ServiceManager");
                //获取方法
                Method getService = serviceManager.getMethod("getService", String.class);
                //使用方法
                IBinder invoke = (IBinder) getService.invoke(null, Context.TELEPHONY_SERVICE);
                ITelephony iTelephony = ITelephony.Stub.asInterface(invoke);
                assert iTelephony != null;
//                if("10086".equals(phone)){
//                    flag = iTelephony.endCall();//挂断电话
//                    Toast.makeText(getApplicationContext(),"方法二：28版本以下：10086被拦截！",Toast.LENGTH_SHORT).show();
//                }
                flag = iTelephony.endCall();//挂断电话
            } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException | RemoteException e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * 初始化通知通道
     */
    private void initNotification() {
        Context context = getApplicationContext();
        //获取系统 通知管理器
        notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        //Android O （8.0）以上版本需要渠道
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel notificationChannel = notificationManager.getNotificationChannel(CHANNEL_ID);
            if (notificationChannel == null) {
                NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
                        CHANNEL_NAME,
                        NotificationManager.IMPORTANCE_MIN  //方法：Android 8.0（API 26）及更高版本
                        //NotificationManager.IMPORTANCE_MIN
                );
                //NotificationManager.IMPORTANCE_HIGH //NONE 为不弹出横幅，HIGH为弹出横幅
                //是否在桌面icon右上角展示小红点
                channel.enableLights(true);
                //小红点颜色
                channel.setLightColor(Color.RED);
                //通知显示
                channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
                //是否在久按桌面图标时显示此渠道的通知
                channel.setShowBadge(true);
                notificationManager.createNotificationChannel(channel);
            }
        }

        Intent intent = new Intent(this , MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this , 0 , intent , 0);

        //创建Notification对象
        builder = new NotificationCompat.Builder(context, CHANNEL_ID)
                .setContentTitle("测试")
//                .setContentText("打卡信息App自动提醒")
                .setWhen(System.currentTimeMillis()) //设置通知被创建的时间,延迟1MIN
                .setSmallIcon(R.mipmap.ic_launcher)//设置出现在状态栏的小图标
                .setPriority(NotificationCompat.PRIORITY_MIN) //方式：Android 7.1（API 25）及更低版本,PRIORITY_HIGH是最高优先级，在所有通知最前面
                .setContentIntent(pendingIntent) //设置点击时跳转的PendingIntent
                .setOngoing(false); //设定为点击后不消失
        Notification notification = builder.build();

        //让通知显示出来 第一个参数是id，要保证每个通知所指定的id各不相同 第二个参数是Notification对象
        notificationManager.notify(notifyId, notification);
        //startForeground(notifyId, notification);

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        //释放锁
        releaseWakeLock();
        //销毁
        stopForeground(true);

        Log.d("cxa", "CallListenerService---->onDestroy，前台service被杀死");

    }

    private PowerManager.WakeLock mWakeLock;
    private void acquireWakeLock() {
        if (mWakeLock ==null) {
            Log.i("Acquiring wake lock","获取wakeLock锁");
            PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
            mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, this.getClass().getCanonicalName());

            mWakeLock.acquire();
        }
    }

    /**
     * 释放wakeLock锁
     * 判断是否已经获取WakeLock： wakeLock.isHeld()
     */
    private void releaseWakeLock() {
        if (mWakeLock !=null&& mWakeLock.isHeld()) {
            Log.i("Acquiring wake unlock","释放wakeLock锁");
            mWakeLock.release();
            mWakeLock =null;
        }
    }

}
